﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports System.Globalization

Namespace Infrastructure

    <AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method, Inherited:=True, AllowMultiple:=True)>
    Public NotInheritable Class CustomAuthorizeAttribute
        Inherits AuthorizeAttribute

        Private userPrivilegesRepositoryValue As IUserPrivilegesRepository

        <CLSCompliant(False)> _
        Public Property UserPrivilegesRepository() As IUserPrivilegesRepository
            Get
                If Me.userPrivilegesRepositoryValue Is Nothing Then
#If SQLONLY Then
                    Me.userPrivilegesRepositoryValue = New SqlDataContext()
#Else
                    Me.userPrivilegesRepositoryValue = New UserTablesServiceContext()
#End If
                End If
                Return Me.userPrivilegesRepositoryValue
            End Get

            Private Set(ByVal value As IUserPrivilegesRepository)
                Me.userPrivilegesRepositoryValue = value
            End Set
        End Property

        Protected Overrides Sub HandleUnauthorizedRequest(ByVal filterContext As AuthorizationContext)
            Dim cookie = filterContext.HttpContext.Request.Cookies(FormsAuthentication.FormsCookieName)
            Dim loginUrl = String.Format(CultureInfo.InvariantCulture, "~/Account/LogOn?returnUrl={0}", filterContext.HttpContext.Request.RawUrl)

            If cookie Is Nothing Then
                filterContext.Result = New RedirectResult(loginUrl)
            Else
                Dim ticket As FormsAuthenticationTicket = Nothing

                Try
                    ticket = FormsAuthentication.Decrypt(cookie.Value)
                Catch e1 As ArgumentException
                    filterContext.Result = New RedirectResult(loginUrl)
                End Try

                If ticket IsNot Nothing Then
                    Dim userId = Membership.GetUser(New FormsIdentity(ticket).Name).ProviderUserKey.ToString()
                    If Not Me.UserPrivilegesRepository.HasUserPrivilege(userId, Me.Roles) Then
                        filterContext.Result = New RedirectResult("~/Account/Unauthorized")
                    End If
                End If
            End If
        End Sub
    End Class
End Namespace